﻿namespace CancellationTokenDemo
{
    internal class Program
    {
        /// <summary>
        /// 按q停止
        /// </summary>
        /// <param name="args"></param>
        /// <returns></returns>
        static async Task Main(string[] args)
        {
            CancellationTokenSource st = new CancellationTokenSource();
            CancellationToken token = st.Token;
            await DownLoad1Async("https://www.baidu.com", 100, token);
            while (Console.ReadLine() != "q")
            {
            }
            st.Cancel();
            Console.ReadLine();
        }

        /// <summary>
        /// 超时5秒停止
        /// </summary>
        /// <param name="args"></param>
        /// <returns></returns>
        static async Task Main1(string[] args)
        {
            await DownLoadAsync("https://www.baidu.com", 100);
            CancellationTokenSource st = new CancellationTokenSource();
            //超时5秒取消
            st.CancelAfter(5000);
            CancellationToken token = st.Token;
            await DownLoad1Async("https://www.baidu.com", 100, token);
            await DownLoad2Async("https://www.baidu.com", 100, token);
        }

        /// <summary>
        /// 无CancellationToken
        /// </summary>
        /// <param name="url"></param>
        /// <param name="n"></param>
        /// <returns></returns>
        static async Task DownLoadAsync(string url, int n)
        {
            using (HttpClient httpClient = new HttpClient())
            {
                for (int i = 0; i < n; i++)
                {
                    string html = await httpClient.GetStringAsync(url);
                    Console.WriteLine($"{DateTime.Now}:{html}");
                }
            }
        }

        /// <summary>
        /// 有CancellationToken，手动处理
        /// </summary>
        /// <param name="url"></param>
        /// <param name="n"></param>
        /// <returns></returns>
        static async Task DownLoad1Async(string url, int n, CancellationToken cancellationToken)
        {
            using (HttpClient httpClient = new HttpClient())
            {
                for (int i = 0; i < n; i++)
                {
                    string html = await httpClient.GetStringAsync(url);
                    Console.WriteLine($"{DateTime.Now}:{html}");
                    //推荐
                    if (cancellationToken.IsCancellationRequested)
                    {
                        Console.WriteLine("请求取消");
                    }
                    //抛出异常
                    //cancellationToken.ThrowIfCancellationRequested();
                }
            }
        }

        /// <summary>
        /// 主动处理
        /// </summary>
        /// <param name="url"></param>
        /// <param name="n"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        static async Task DownLoad2Async(string url, int n, CancellationToken cancellationToken)
        {
            using (HttpClient httpClient = new HttpClient())
            {
                for (int i = 0; i < n; i++)
                {
                    var res = await httpClient.GetAsync(url, cancellationToken);
                    string html = await res.Content.ReadAsStringAsync();
                    Console.WriteLine($"{DateTime.Now}:{html}");
                }
            }
        }

        /// <summary>
        /// CancellationToken既有主动又有手动处理
        /// </summary>
        /// <param name="url"></param>
        /// <param name="n"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        static async Task DownLoad3Async(string url, int n, CancellationToken cancellationToken)
        {
            using (HttpClient httpClient = new HttpClient())
            {
                for (int i = 0; i < n; i++)
                {
                    var res = await httpClient.GetAsync(url, cancellationToken);
                    string html = await res.Content.ReadAsStringAsync();
                    Console.WriteLine($"{DateTime.Now}:{html}");
                    if (cancellationToken.IsCancellationRequested)
                    {
                        Console.WriteLine("请求取消");
                    }
                }
            }
        }
    }
}